package chabernac.android.wordbattle.rastersolver;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import chabernac.android.wordbattle.db.iStringDatabase;
import chabernac.android.wordbattle.model.Letter;
import chabernac.android.wordbattle.model.WordRaster;

public class WordRasterSolverHelper {

  public static final int MINIMUM_WORD_LENGTH = 3;  
  public static final int DEFAULT_PUZZLE_SIZE = 4;  
  
  private StringBuilder theStringSoFar = new StringBuilder();
  public Set<String> myResults = new HashSet<String>();
  
  private final int myMinimumWordLength;
  private final WordRaster myWordWraster;
  private final iStringDatabase myStringDatabase;

  public WordRasterSolverHelper(iStringDatabase aStringDatabase, int aMinWordLength, WordRaster aWordRaster){
    myStringDatabase = aStringDatabase;
    myWordWraster = aWordRaster;
    myMinimumWordLength = aMinWordLength;
  }

  public void solve(){
    //start from each letter of the raster as a starting letter
    for(Letter[] theRow : myWordWraster.getRaster()){
      for(Letter theLetter : theRow){
        runThrough(theLetter);
      }
    }
  }

  List<Letter> aListOfUsedLetters = new ArrayList<Letter>();

  private void runThrough(Letter aStartingLetter){

    theStringSoFar.append(aStartingLetter.getChar());
    aListOfUsedLetters.add(aStartingLetter);

    //Check if we have a valid word  
    if ((theStringSoFar.length() >= myMinimumWordLength) && (myStringDatabase.isValidWord( myWordWraster.getLanguage(), theStringSoFar.toString())))  
    {
      //GC if we do not create a new string it seams like the string is being modified afterwards when the stringbuilder changes!
      //verry ackward!!
      myResults.add(new String(theStringSoFar.toString()));
    } 

    for (Letter l : myWordWraster.getNeighbours(aStartingLetter)){
      if ( !aListOfUsedLetters.contains(l) && myStringDatabase.isValidPrefix( myWordWraster.getLanguage(), theStringSoFar.toString() + l.getChar()))  
      {  
        runThrough(l);  
      }
    }
    aListOfUsedLetters.remove(aStartingLetter);
    theStringSoFar.deleteCharAt(theStringSoFar.length() - 1);
  }

  public Set<String> getResults() {
    return myResults;
  }
}

